package com.example.movie.data.user.model

import android.os.Build
import androidx.annotation.RequiresApi
import com.example.movie.common.model.BaseResponse
import com.example.movie.common.model.Result
import com.example.movie.data.movie.model.bean.ApproveBean
import com.example.movie.data.movie.model.vo.ForumVo
import com.example.movie.data.movie.model.vo.SearchVo
import com.example.movie.data.user.login.model.LoggedInUser
import com.example.movie.data.user.model.vo.OrderVo
import com.example.movie.ui.video.bean.VideoVo
import com.example.movie.utils.VideoBean
import okhttp3.RequestBody

/**
 * Class that requests authentication and user information from the remote data source and
 * maintains an in-memory cache of login status and user credentials information.
 */

class UserRepository(val dataSource: UserDataSource) {

    // in-memory cache of the loggedInUser object
    private var loggedInUser: LoggedInUser? = null

    val isLoggedIn: Boolean
        get() = loggedInUser != null

    init {
        // If user credentials will be cached in local storage, it is recommended it be encrypted
        // @see https://developer.android.com/training/articles/keystore
        loggedInUser = null
    }

    fun logout(): Result<Any> {
        val result = dataSource.logout()
        if (result is Result.Success) {
            loggedInUser = null
        }
        return result
    }

    fun login(username: String, password: String): Result<LoggedInUser> {
        // handle login
        val result = dataSource.login(username, password)
        if (result is Result.Success) {
            setLoggedInUser(result.data)
        }
        return result
    }

    private fun setLoggedInUser(loggedInUser: LoggedInUser?) {
        this.loggedInUser = loggedInUser
        // If user credentials will be cached in local storage, it is recommended it be encrypted
        // @see https://developer.android.com/training/articles/keystore
    }

    fun register(username: String, password: String): Result<Any> {
        return dataSource.register(username, password)
    }

    fun addOrder(ids: String, planId: Int): Result<Any> {
        return dataSource.addOrder(ids,planId)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun newOrder(): Result<List<OrderVo>> {
        return dataSource.newOrder()
    }

    fun loadUserInfo(): Result<LoggedInUser>? {
        val result = dataSource.loadUserInfo()
        if (result is Result.Success) {
            setLoggedInUser(result.data)
        }
        return result
    }

    fun updateUser(user: LoggedInUser, headImage: RequestBody?): Result<Boolean> {
        return dataSource.saveUserData(user,headImage)
    }

    fun loadMyMovieList(type: Int): Result<List<SearchVo>> {
        return dataSource.loadMyMovieList(type)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun successOrder(): Result<List<OrderVo>>? {
        return dataSource.successOrder()
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun expireOrder(): Result<List<OrderVo>>? {
        return dataSource.expireOrder()
    }

    fun loadVideoData():Result<List<VideoVo>> {
        return dataSource.loadVideoData()
    }

    fun like(vid: Long): Result<Boolean> {
        return dataSource.like(vid)
    }

    fun loadForumPage(vid: Long, page: Int, size: Int): Result<BaseResponse<List<ForumVo>>>? {
        return dataSource.loadForumPage(vid,page,size)
    }

    fun approve(forumId: Int): Result<ApproveBean>? {
        return dataSource.approve(forumId)
    }

    fun loadReplies(pid: Long, page: Int, size: Int): Result<BaseResponse<List<ForumVo>>>? {
        return dataSource.loadReplies(pid,page,size)
    }

    fun addForum(vid: Long, content: String, pid: Int, toId: String?): Result<Int>? {
        return dataSource.addForum(vid,content,pid,toId)
    }

    fun loadMyLikeMovieVideoList(): Result<List<VideoBean>>? {
        return dataSource.loadMyLikeMovieVideoList()
    }

}